#include "fxcc/core/graph/opengl3/Texture2DArrayJack.h"
#include "fxcc/core/graph/opengl3/RenderTargetJack.h"
#include "fxcc/core/graph/opengl3/Effect3d.h"

fxcc::graph::opengl3::Texture2DArrayJack::Texture2DArrayJack(const Desc& desc)
	:fxcc::graph::opengl3::Texture(GL_TEXTURE_2D_ARRAY), fxcc::graph::common::Texture2DArrayJack(desc)
{
	m_Available = Init();
}

bool fxcc::graph::opengl3::Texture2DArrayJack::InitDDS()
{
	if (!fs::exists(m_Desc.m_DDSPath))
	{
		ztclog::info("failed find the dds path %s", m_Desc.m_DDSPath);
		return false;
	}

	m_Id = gliUtils2::create_texture(m_Desc.m_DDSPath.c_str());
	Bind();
	SetSampler(m_Desc.m_SamplerType);
	UnBind();


	{
		gli::texture texture = gli::load(m_Desc.m_DDSPath.c_str());
		auto Extent0 = texture.extent();
		//auto layer = texture.layers();
		//auto faces = texture.faces();
		auto fmt = texture.format();
		m_MipmapConfig.m_Width = Extent0.x;
		m_MipmapConfig.m_Height = Extent0.y;
		m_MipmapConfig.m_Depth = texture.layers();
		m_MipmapConfig.m_NrComponent = gli::component_count(fmt);
		m_MipmapConfig.m_HDR = gli::is_float(fmt);
	}

	return true;
}

bool fxcc::graph::opengl3::Texture2DArrayJack::Init()
{
	switch (m_Desc.m_Type)
	{
	case Desc::Type::_DDS_:
		return InitDDS();
	default:
		return false;
	}
}

bool fxcc::graph::opengl3::Texture2DArrayJack::GenerateTextures()
{
	ResizeTextures();

	std::shared_ptr<fxcc::graph::opengl3::Effect3d> m_ArrayEffect;

	auto m_QuadMesh = std::make_shared<fxcc::graph::opengl3::MeshJack>(fxcc::graph::common::Geometry::CreateQuad2());

	{

		m_ArrayEffect = std::make_shared<fxcc::graph::opengl3::Effect3d>(GetArrayIndexFragCode());
		m_ArrayEffect->m_PipeLineType.m_RasterizerType = fxcc::graph::common::RasterizerType::_NONE_;
	}


	for (int index = 0; index < m_MipmapConfig.m_Depth; index++)
	{
		//ztclog::info("index is %d", index);
		fxcc::graph::common::RenderTargetJack::Desc desc(1, m_MipmapConfig);
		auto m_RTJack = std::make_shared<fxcc::graph::opengl3::RenderTargetJack>(desc);

		m_RTJack->Begin();
		glClearColor(0, 0, 0, 0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		m_ArrayEffect->Begin();
		fxcc::graph::common::Effect3d::PassData passData;
		fxcc::graph::common::Effect3d::ObjData objData;
		m_ArrayEffect->GetTexture2DJackBufferData(m_MipmapConfig, passData, objData);
		m_ArrayEffect->SetPassData(passData);
		m_ArrayEffect->SetObjData(objData);
		m_ArrayEffect->m_Shader->Use();
		m_ArrayEffect->m_Shader->setInt("index", index);
		m_ArrayEffect->m_Shader->setInt("diffuse", 0);
		Active(0);
		m_ArrayEffect->InstMeshJack(m_QuadMesh.get());
		m_ArrayEffect->End();

		m_RTJack->End();
		m_Textures[index] = m_RTJack->m_Textures[0];

	};

	return true;
}

const std::string fxcc::graph::opengl3::Texture2DArrayJack::GetArrayIndexFragCode()
{
	const std::string fragCode = R"(

out vec4 FragColor;

uniform sampler2DArray diffuse;

uniform int index;

uniform int useArray;

void main()
{
    FragColor = texture(diffuse, vec3(TexCoord, float(index)));
}
)";

	return fragCode;

}
